package ogmios.dialogs;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.text.*;
import javax.swing.text.*;
import java.beans.*;

/**
 * A dialog for selecting a font.
 */
public class FontDialog extends JDialog
{
  private JTextField fontName;
  private JList fontList;
  private JRadioButton bold, italics, plain, boldItalics;
  private JButton okButton, cancelButton;
  private JLabel preview;
  private JFormattedTextField fontSize;
  private Font selectedFont;
  private JList sizeList;
  private DefaultListModel sizeItems;
  private boolean accept = false;

  public static Font showDialog(Frame parent, Font initFont, String title)
  {
    FontDialog fd = new FontDialog(parent, initFont, title);
    fd.setModal(true);
    fd.setVisible(true);
    return fd.accept ?  fd.selectedFont : null;
  }


  private FontDialog(Frame parent, Font initFont, String title)
  {
    super(parent);
    setTitle(title != null ? title : "Font");
    setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
    preview = new JLabel();

    if (initFont != null)
      preview.setFont(initFont);

    selectedFont = preview.getFont();


    preview.setText("Preview");
    fontName = new JTextField();
    fontName.setEditable(false);
    fontList = new JList();
    fontList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    fontList.setListData(GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames());
    sizeItems = new DefaultListModel();
    sizeList = new JList(sizeItems);
    for (int i = 8; i <= 72; i += 2)
      sizeItems.addElement(i);
    fontSize = new JFormattedTextField(NumberFormat.getIntegerInstance());

    ButtonGroup btns = new ButtonGroup();
    btns.add(plain = new JRadioButton("Plain"));
    btns.add(italics = new JRadioButton("Italics"));
    btns.add(bold = new JRadioButton("Bold"));
    btns.add(boldItalics = new JRadioButton("Bold Italics"));

    okButton = new JButton("Ok");
    cancelButton = new JButton("Cancel");


    JPanel p = new JPanel();
    p.setLayout(new GridLayout(1, 3));
    JPanel fontNamePanel = new JPanel();
    JScrollPane fontScroll = new JScrollPane(fontList);
    JPanel sizePanel = new JPanel();
    sizePanel.setLayout(new BorderLayout());

    sizePanel.add(fontSize, BorderLayout.NORTH);
    sizePanel.add(new JScrollPane(sizeList));

    sizePanel.setBorder(BorderFactory.createTitledBorder("Font Size"));

    JPanel stylePanel = new JPanel();
    stylePanel.setLayout(new GridLayout(4, 1));
    stylePanel.add(plain);
    stylePanel.add(italics);
    stylePanel.add(bold);
    stylePanel.add(boldItalics);
    stylePanel.setBorder(BorderFactory.createTitledBorder("Font Style"));
    JPanel bottomPanel = new JPanel();
    JPanel previewPanel = new JPanel();
    previewPanel.setBorder(BorderFactory.createTitledBorder("Preview"));
    previewPanel.add(preview);
    bottomPanel.setLayout(new BorderLayout());
    bottomPanel.add(previewPanel, BorderLayout.NORTH);
    fontNamePanel.setLayout(new BorderLayout());
    fontNamePanel.setBorder(BorderFactory.createTitledBorder("Font Family"));
    fontNamePanel.add(fontName, BorderLayout.NORTH);
    fontNamePanel.add(fontScroll);

    JPanel buttonPanel = new JPanel();

    buttonPanel.setLayout(new GridLayout(1, 2));
    buttonPanel.add(okButton);
    buttonPanel.add(cancelButton);
    bottomPanel.add(buttonPanel, BorderLayout.SOUTH);
    p.add(fontNamePanel);
    p.add(sizePanel);
    p.add(stylePanel);

    JPanel jspPanel = new JPanel();
    JScrollPane jsp = new JScrollPane(jspPanel);
    setContentPane(jsp);
    jspPanel.setLayout(new BorderLayout());
    jspPanel.add(p);


    jspPanel.add(bottomPanel, BorderLayout.SOUTH);


    fontList.addListSelectionListener(
      new ListSelectionListener()
    {
      public void valueChanged(ListSelectionEvent e)
      {
        String name;
        fontName.setText(name = fontList.getSelectedValue().toString());
        selectedFont = new Font(name, selectedFont.getStyle(), selectedFont.getSize());
        preview.setFont(selectedFont);
      }
    }
    );
    sizeList.addListSelectionListener(
      new ListSelectionListener()
    {
      public void valueChanged(ListSelectionEvent e)
      {
        int size;
        String name;
        fontSize.setText(name = sizeList.getSelectedValue().toString());
        size = Integer.parseInt(name);
        selectedFont = new Font(selectedFont.getFamily(), selectedFont.getStyle(), size);
        preview.setFont(selectedFont);
      }
    }
    );
    fontSize.addPropertyChangeListener("value",
                                       new PropertyChangeListener()
    {
      public void propertyChange(PropertyChangeEvent e)
      {
        Number num;
        int size;
        if ((num = (Number)fontSize.getValue()) != null)
        {
          fontSize.setText(num.toString());
          size = num.intValue();
          sizeList.setSelectedIndex(sizeItems.indexOf(size));
          selectedFont = new Font(selectedFont.getFamily(), selectedFont.getStyle(), size);
          preview.setFont(selectedFont);
        }
      }
    }

                                      );

    okButton.addActionListener(
      new ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        accept = true;
        setVisible(false);
      }
    }
    );
    cancelButton.addActionListener(
      new ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        setVisible(false);
      }
    }
    );


    int style = selectedFont.getStyle();
    btns.setSelected(
      style == (Font.BOLD | Font.ITALIC) ? boldItalics.getModel() :
      style == Font.BOLD ? bold.getModel() :
      style == Font.ITALIC ? italics.getModel() :
      plain.getModel(), true);


    ItemListener itmListener =
      new ItemListener()
    {
      public void itemStateChanged(ItemEvent e)
      {
        if (e.getStateChange() == ItemEvent.SELECTED)
        {
          JRadioButton itm = (JRadioButton)e.getItem();
          selectedFont = selectedFont.deriveFont(
                           itm == plain ? Font.PLAIN :
                           itm == italics ? Font.ITALIC :
                           itm == bold ? Font.BOLD :
                           Font.BOLD | Font.ITALIC);
          preview.setFont(selectedFont);
        }
      }
    };
    bold.addItemListener(itmListener);
    plain.addItemListener(itmListener);
    boldItalics.addItemListener(itmListener);
    italics.addItemListener(itmListener);

    fontList.setSelectedValue(selectedFont.getFamily(), true);

    fontSize.setValue(selectedFont.getSize());

    pack();
  }


}
